package com.tange.module.login.google;

import static com.appbase.custom.constant.CommonConstants.LOGIN_CHANNEL_GOOGLE;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;

import com.appbase.custom.constant.CommonConstants;
import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.tasks.Task;
import com.demo.view.LoadingDialog;
import com.tange.base.toolkit.PreferenceUtil;
import com.tange.base.toolkit.StatusBarUtil;
import com.tange.core.backend.service.interceptor.HttpLoggingInterceptor;
import com.tange.core.builtin.account.LoginRet;
import com.tange.core.builtin.account.third.ThirdAccount;
import com.tg.appcommon.android.LanguageUtils;
import com.tg.appcommon.android.TGLog;
import com.tg.appcommon.android.TGToast;
import com.tg.appcommon.router.TGBusiness;
import com.tg.data.http.entity.LoginBean;
import com.tg.loginex.helper.LoginHelper;

public class GoogleLoginActivity extends Activity {

    private static final int SIGN_IN_REQ_CODE = 1988;

    private static final String TAG = "GoogleLoginActivityTAG";

    private static final int MAX_RETRY_COUNT = 1;

    private int retryCount = 0;

    private LoadingDialog mLoadingDialog;

    protected void showLoading() {
        if (mLoadingDialog == null) {
            mLoadingDialog = new LoadingDialog(this);
            mLoadingDialog.setMsg(R.string.loging);
            mLoadingDialog.setCancelable(false);
        }
        if (!isFinishing() && !isDestroyed()) {
            mLoadingDialog.show();
        }
    }

    protected void hideLoading() {
        if (mLoadingDialog != null && mLoadingDialog.isShowing()) {
            mLoadingDialog.cancel();
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        StatusBarUtil.setStatusBarTransparent(this);

        setContentView(R.layout.activity_google_login);

        showLoading();

        TGLog.i(TAG, "onCreate: ");

        GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this);
        if (account != null && !account.isExpired()) {
            TGLog.i(TAG, "onCreate: login success before !");
            notifySuccess(account);
            return;
        }

        final boolean isGooglePlayServicesAvailable = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS;
        if (!isGooglePlayServicesAvailable) {
            TGLog.i(TAG, "onCreate: no google service found");
            Intent intent = new Intent();
            intent.putExtra("msg", getResources().getString(R.string.login_been_canceled));
            setResult(RESULT_CANCELED, intent);
            finish();
            TGToast.showToast(R.string.google_app_not_installed);
            return;
        }

        startNewGoogleLogin();
    }

    private void startNewGoogleLogin() {
        GoogleSignInOptions googleSignInOptions = new GoogleSignInOptions
                .Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestIdToken(getString(R.string.tange_third_login_google_client_id))
                .build();

        GoogleSignInClient googleSignInClient = GoogleSignIn.getClient(this, googleSignInOptions);
        Intent signInIntent = googleSignInClient.getSignInIntent();
        startActivityForResult(signInIntent, SIGN_IN_REQ_CODE);

        TGLog.i(TAG, "startNewGoogleLogin: start a new login ...");
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            TGLog.i(TAG, "ignore KEYCODE_BACK");
            return true;
        } else {
            return super.onKeyDown(keyCode, event);
        }
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        TGLog.i(TAG, "[onActivityResult]");
        if (requestCode == SIGN_IN_REQ_CODE) {
            Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
            GoogleSignInAccount account;
            try {
                account = task.getResult(ApiException.class);
                if (account != null && !account.isExpired()) {
                    TGLog.i(TAG, "[onActivityResult] account.getId() : " + account.getId());
                    TGLog.i(TAG, "[onActivityResult] account.getEmail() : " + account.getEmail());
                    TGLog.i(TAG, "[onActivityResult] account.getDisplayName() : " + account.getDisplayName());

                    notifySuccess(account);
                } else {
                    TGLog.i(TAG, "[onActivityResult] account null or expired");
                    Intent retIntent = new Intent();
                    retIntent.putExtra("msg", "account null or expired");
                    TGToast.showToast("[Google Error] " + "account null or expired");
                    setResult(RESULT_CANCELED);
                    finish();
                }
            } catch (ApiException e) {

                TGLog.i(TAG, "[onActivityResult] error status : " + e.getStatusMessage());
                TGLog.i(TAG, "[onActivityResult] error msg : " + e.getMessage());
                TGLog.i(TAG, "signInResult:failed code =: " + e.getStatusCode());
                TGLog.i(TAG, "[onActivityResult] error detail : " + Log.getStackTraceString(e));
                TGToast.showToast("[Google Error] " + e.getMessage());
                Intent retIntent = new Intent();
                retIntent.putExtra("msg", e.getMessage());
                setResult(RESULT_CANCELED);
                finish();
            }
        }
    }

    private void loginWithTG(final GoogleSignInAccount account) {
        if (account == null) {
            TGLog.i(TAG, "loginWithTG: account is null");
            TGToast.showToast("account is null");
            return;
        }

        final String userName = TextUtils.isEmpty(account.getDisplayName()) ? "Google User" : account.getDisplayName();
        HttpLoggingInterceptor.enableLogging = true;
        ThirdAccount.INSTANCE.google(account.getIdToken(), LanguageUtils.getCountry(this), loginRetResp -> {
            if (loginRetResp == null){
                return;
            }
            if (loginRetResp.getSuccess()){
                LoginRet loginRet = loginRetResp.getData();
                if (loginRet != null){
                    LoginBean content = new LoginBean();
                    content.setNickname(account.getDisplayName());
                    content.setToken(loginRet.getAccessToken());
                    content.setId(String.valueOf(loginRet.getId()));
                    long expiresInSeconds = loginRet.getExpiresInSeconds() * 1000 + System.currentTimeMillis();
                    content.setCreated_at(expiresInSeconds);
                    TGLog.i(TAG, "loginWithTG: onSuccess: " + content);
                    final Handler h = new Handler(Looper.getMainLooper());
                    h.post(() -> {
                        String token = loginRet.getAccessToken();

                        Intent retIntent = new Intent();
                        retIntent.putExtra("token", token);
                        retIntent.putExtra("name", account.getDisplayName());
                        retIntent.putExtra("id", content.getId());
                        setResult(RESULT_OK);
                        finish();

                        PreferenceUtil.setBoolean(GoogleLoginActivity.this, CommonConstants.PRE_PROTOCOL_AGREE,true);
                        LoginHelper.saveUserInfo(content, userName, "");
                        LoginHelper.saveLastLoginChannel(LOGIN_CHANNEL_GOOGLE);
                        TGBusiness.getAppModule().goToDeviceListPage(GoogleLoginActivity.this);
                    });
                }

            }else{
                TGLog.i(TAG, "loginWithTG: onResponseError: errorCode = " + loginRetResp.getCode() + " , errorInfo = " + loginRetResp.getMessage());
                if (retryCount < MAX_RETRY_COUNT) {
                    retryCount++;
                    TGLog.i(TAG, "loginWithTG: onResponseError: retry ... ");

                    // 只要后台返回错误，就注销之前的信息，重新发起登录
                    GoogleLoginProxy.logout(GoogleLoginActivity.this, () -> {
                        TGLog.i(TAG, "loginWithTG: onResponseError: start new login ");
                        startNewGoogleLogin();
                    });
                } else {
                    TGToast.showToast("[TG-ERROR] " + loginRetResp.getCode() + " , " + loginRetResp.getMessage());
                    finish();
                }
            }

        });

    }

    private void notifySuccess(GoogleSignInAccount account) {
        TGLog.i(TAG, "[notifySuccess] account = " + account);
        if (account != null) {
            loginWithTG(account);
        }
    }

    @Override
    protected void onDestroy() {
        TGLog.i(TAG, "[onDestroy]");
        super.onDestroy();
        hideLoading();
    }
}
